/**
 * @author ternst
 * 
 * My attempt to learn javascript....
 */

var g_GameBoard;
var APPLE = 1;
var SCISSORS = 2;
var root = "http://tydev.googlecode.com/svn/trunk/";

function init()
{	
	g_GameBoard = new createBoard(20, 20);
	g_GameBoard.initBoard();
		
	//window.onkeydown = keyListener;	
	document.onkeypress = keyListener;
	document.onkeydown = keyListener;
	
	gameLoop();
}

function gameLoop()
{
	g_GameBoard.updateBoard(50);
	
	setTimeout('gameLoop()', 50);
}

function keyListener(e)
{
	if(!e)
		e = window.event;
		
	//Get to cell the crawlers head is in.
	//left
	if(e.keyCode == '37')
	{
		var seg = g_GameBoard.m_Crawler.m_Body[0];
		if(seg.m_Dx != 0)
			return;
		seg.m_Dx = -1;
		seg.m_Dy = 0;
		
		g_GameBoard.m_Crawler.changeCrawlerHead(root + "res/head_left.png");
	}
	//up
	else if(e.keyCode == '38')
	{
		var seg = g_GameBoard.m_Crawler.m_Body[0];
		if(seg.m_Dy != 0)
			return;
		seg.m_Dx = 0;
		seg.m_Dy = -1;
		g_GameBoard.m_Crawler.changeCrawlerHead(root + "res/head_up.png");
	}
	//right
	else if(e.keyCode == '39')
	{
		var seg = g_GameBoard.m_Crawler.m_Body[0];
		if(seg.m_Dx != 0)
			return;
		seg.m_Dx = 1;
		seg.m_Dy = 0;
		
		g_GameBoard.m_Crawler.changeCrawlerHead(root + "res/head_right.png");
	}
	//down
	else if(e.keyCode == '40')
	{
		var seg = g_GameBoard.m_Crawler.m_Body[0];
		if(seg.m_Dy != 0)
			return;
		seg.m_Dx = 0;
		seg.m_Dy = 1;
		
		g_GameBoard.m_Crawler.changeCrawlerHead(root + "res/head_down.png");
	}
}

function createCrawler(x, y)
{
	this.m_X = x;
	this.m_Y = y;
	this.m_MoveTime = 0;
	this.m_SegmentCounter = 0;
	
	this.m_NewSegments = new Array();
	this.m_Body = new Array();
	this.updateCrawler = updateCrawler;
	this.addSegment = addSegment;
	this.startGameOver = startGameOver;
	this.changeCrawlerHead = changeCrawlerHead;
	this.removeSegments = removeSegments;
	
	var headSegment = new createSegment('seg', x, y, 1, 0);
	this.addSegment(headSegment);
	
	for(var i = 0; i < 5; ++i)
	{
		var seg = new createSegment('seg', 0, 0, 0, 0);
		this.m_NewSegments.push(seg);
	}
}

function updateCrawler(elapsedTime)
{	
	this.m_MoveTime += elapsedTime;	
	
	if(this.m_MoveTime > 100)
	{
		var lastX = 0;
		var lastY = 0;
		var dx = 0;
		var dy = 0;
		
		//Update the position of the crawler
		for(var i = 0; i < this.m_Body.length; ++i)
		{
			var seg = this.m_Body[i];
			lastX = seg.m_X;
			lastY = seg.m_Y;
			dx = seg.m_Dx;
			dy = seg.m_Dy;
			seg.m_X += seg.m_Dx;
			seg.m_Y += seg.m_Dy;
			
			if(seg.m_X >= g_GameBoard.m_Rows)
				seg.m_X = seg.m_X % g_GameBoard.m_Rows;
			if(seg.m_Y >= g_GameBoard.m_Cols)
				seg.m_Y = seg.m_Y % g_GameBoard.m_Cols;
			if(seg.m_X < 0)
				seg.m_X = g_GameBoard.m_Rows + seg.m_X;
			if(seg.m_Y < 0)
				seg.m_Y = g_GameBoard.m_Cols + seg.m_Y;
				
			var node = document.getElementById(seg.m_Id);
			node.style.left = (seg.m_X * g_GameBoard.m_CellWidth) + 'px';
			node.style.top = (seg.m_Y * g_GameBoard.m_CellHeight) + 'px';
		}
		
		for(var i = this.m_Body.length - 1; i > 0; --i)
		{
			var seg = this.m_Body[i];
			var prev = this.m_Body[i - 1];
			
			seg.m_Dx = prev.m_Dx;
			seg.m_Dy = prev.m_Dy;
		}
		
		//Add new segments to the crawler.
		if(this.m_NewSegments.length > 0)
		{
			var newSeg = this.m_NewSegments.pop();
			newSeg.m_X = lastX;
			newSeg.m_Y = lastY;
			newSeg.m_Dx = dx;
			newSeg.m_Dy = dy;
			
			this.addSegment(newSeg);
		}
		
		//Check if the head has collided with anything.
		var head = this.m_Body[0];
		
		//Check if the head has collided with its body.
		for(var i = 1; i < this.m_Body.length; ++i)
		{
			var seg = this.m_Body[i];
			
			if (seg.m_X == head.m_X && seg.m_Y == head.m_Y) 
			{
				this.startGameOver();
				break;
			}
		}
		
		//Check if the head has collided with an item.
		for(var i = 0; i < g_GameBoard.m_Items.length; ++i)
		{
			var item = g_GameBoard.m_Items[i];
			
			if(item.m_X == head.m_X && item.m_Y == head.m_Y)
			{
				g_GameBoard.updateScore(item.m_Points);
				
				if(item.m_Type == APPLE)
				{
					var seg = new createSegment('seg', 0, 0, 0, 0);
					this.m_NewSegments.push(seg);
				}
				else if(item.m_Type == SCISSORS)
				{
					this.removeSegments(3);
				}
				
				removeObject(item.m_Id);
				g_GameBoard.m_Items.splice(i, 1);
				break;
			}
		}
		
		var asdf = document.getElementById('segments');
		asdf.innerHTML = "Segments: " + this.m_Body.length;
		
		this.m_MoveTime = 0;
	}	
}

function startGameOver()
{
	var board = document.getElementById('gameboard');
	
	var newDiv = document.createElement('div');
	newDiv.setAttribute('id', 'dasdf');
	newDiv.innerHTML = 'Game Over!!';
	board.appendChild(newDiv);
	
	//Change to the dead head.
	var head = this.m_Body[0];
	
	var crawlerHead = document.getElementById(head.m_Id);
	crawlerHead.innerHTML = '<img src="' + root + 'res/head_dead.png" width="' + 
						g_GameBoard.m_CellWidth + '" height="' + g_GameBoard.m_CellHeight + '">';
	
	
	g_GameBoard.m_bGameOver = true;
}

function changeCrawlerHead(src)
{
	var board = document.getElementById('gameboard');
	
	var head = this.m_Body[0];
	
	var crawlerHead = document.getElementById(head.m_Id);
	crawlerHead.innerHTML = '<img src="' + src + '" width="' + 
						g_GameBoard.m_CellWidth + '" height="' + g_GameBoard.m_CellHeight + '">';
}

function removeSegments(numSegments)
{
	for(var i = 0; i < numSegments; ++i)
	{
		if(this.m_Body.length == 1)
			return;
			
		var seg = this.m_Body.pop();
		removeObject(seg.m_Id);
	}
}

function addSegment(segment)
{
	segment.m_Id = 'seg' + this.m_SegmentCounter++;
	var board = document.getElementById('gameboard');
	
	var newDiv = document.createElement('div');
	
	var l = (segment.m_X * g_GameBoard.m_CellWidth);
	var t = (segment.m_Y * g_GameBoard.m_CellHeight);
	
	if(this.m_SegmentCounter == 1)
		newDiv.setAttribute('style', 'position:absolute; z-index:2;');
	else	
		newDiv.setAttribute('style', 'position:absolute;');
	newDiv.setAttribute('id', segment.m_Id);
	newDiv.innerHTML = '<img src="' + root + 'res/section.png" width="' + 
						g_GameBoard.m_CellWidth + '" height="' + g_GameBoard.m_CellHeight + '">';
	newDiv.style.left = (segment.m_X * g_GameBoard.m_CellWidth) + 'px';
	newDiv.style.top = (segment.m_Y * g_GameBoard.m_CellHeight) + 'px';
	
	board.appendChild(newDiv);
	
	this.m_Body.push(segment);
}

function createSegment(id, x, y, dx, dy)
{
	this.m_Id = id;	
	this.m_X = x;
	this.m_Y = y;
	this.m_Dx = dx;
	this.m_Dy = dy;
}

function createMoveCell(x, y, dx, dy)
{
	this.m_X = x;
	this.m_Y = y;
	this.m_Dx = dx;
	this.m_Dy = dy;
}

function createBoard(cellWidth, cellHeight)
{
	this.m_CellWidth = cellWidth;
	this.m_CellHeight = cellHeight;
	this.m_Rows = 20;
	this.m_Cols = 20;
	this.m_Crawler;
	this.m_ItemCounter = 0;
	this.m_Items = new Array();
	this.m_UpdateTime = 0;
	this.m_Score = 0;
	this.m_bGameOver = false;
	
	//Add the boards functions.
	this.updateBoard = updateBoard;
	this.initBoard = initBoard;
	this.addItem = addItem;
	this.updateScore = updateScore;
}

function initBoard()
{
	this.m_Crawler = new createCrawler(this.m_CellWidth, this.m_CellHeight);
}

function updateScore(points)
{
	this.m_Score += points;
	
	var score = document.getElementById('score');
	score.innerHTML = "Score: " + this.m_Score;
}

function updateBoard(elapsedTime)
{
	this.m_UpdateTime += elapsedTime;
	
	if(this.m_bGameOver == true)
		return;
		
	this.m_Crawler.updateCrawler(elapsedTime);
	
	if(this.m_UpdateTime > 500)
	{
		var x = 0;
		var y = 0;
		var bFoundConflict = false;
		
		do
		{
			x = Math.floor(Math.random() * this.m_Rows);
			y = Math.floor(Math.random() * this.m_Cols);
			bFoundConflict = false;
			
			//Make sure the crawler is not at this position.
			for(var i = 1; i < this.m_Crawler.m_Body.length; ++i) 
			{
				var seg = this.m_Crawler.m_Body[i];
				
				if(seg.m_X == x && seg.m_Y == y)
				{
					bFoundConflict = true;
					break;
				}
			}
			
			if(bFoundConflict == true)
				continue;
			
			//Make sure another item is not at this position.
			for(var i = 0; i < this.m_Items.length; ++i)
			{
				var item = this.m_Items[i];
				
				if(item.m_X == x && item.m_Y == y)
				{
					bFoundConflict = true;
					break;
				}
			}
			
			if(bFoundConflict == false)
				break;
			
		}while(bFoundConflict == true);
		
		var num = Math.floor(Math.random() * 10);
		var item;
		if(num  < 7)
			item = new createItem(APPLE, x, y, 500);
		else
			item = new createItem(SCISSORS, x, y, 0);
			
		this.addItem(item);
	
		this.m_UpdateTime = 0;
	}
}

function createItem(type, x, y, points)
{
	this.m_X = x;
	this.m_Y = y;
	this.m_Points = points;
	this.m_Type = type;
	this.m_Id = "item";
}

function addItem(item)
{	
	item.m_Id = 'item' + this.m_ItemCounter++;
	var board = document.getElementById('gameboard');
	
	var newDiv = document.createElement('div');
	newDiv.setAttribute('style', 'position:absolute;');
	newDiv.setAttribute('id', item.m_Id);
	if (item.m_Type == APPLE) {
		newDiv.innerHTML = '<img src="' + root + 'res/apple.png" width="' +
		this.m_CellWidth +
		'" height="' +
		this.m_CellHeight +
		'">';
	}
	else
	{
		newDiv.innerHTML = '<img src="' + root + 'res/scissors.png" width="' + this.m_CellWidth +
													'" height="' + this.m_CellHeight + '">';
	}
	newDiv.style.left = (item.m_X * this.m_CellWidth) + 'px';
	newDiv.style.top = (item.m_Y * this.m_CellHeight) + 'px';
	
	board.appendChild(newDiv);
	
	this.m_Items.push(item);
}

function removeObject(id)
{
	var board = document.getElementById('gameboard');
	var child = document.getElementById(id);
	
	if(child != 0 && board != 0)
		board.removeChild(child);
}

